/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cx1.web.controller;

import com.javadocmd.simplelatlng.LatLng;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.spring.web.servlet.view.JsonView;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.cx1.model.Amenity;
import org.cx1.model.FurnishType;
import org.cx1.model.Listing;
import org.cx1.model.Place;
import org.cx1.model.PropertyType;
import org.cx1.model.StatusType;
import org.cx1.model.utils.KFurnishTypes;
import org.cx1.model.utils.KPropertyTypes;
import org.cx1.model.utils.KStatusTypes;
import org.cx1.model.utils.ListingFilter;
import org.cx1.model.utils.SearchOption;
import org.cx1.model.utils.SearchResult;
import org.cx1.model.utils.ServiceResponse;
import org.cx1.model.utils.SystemProperties;
import org.cx1.service.api.IAmenityService;
import org.cx1.service.api.IPlaceService;
import org.cx1.service.api.ISearchService;
import org.cx1.service.impl.DAmenityService;
import org.cx1.service.impl.DPlaceService;
import org.cx1.service.impl.DSearchService;
import org.cx1.service.impl.MAmenityService;
import org.cx1.service.impl.MPlaceService;
import org.cx1.service.impl.MSearchService;
import org.cx1.web.controller.action.SearchAction;
import org.cx1.web.utils.SessionUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

/**
 *
 * @author ECH
 */
public class GeoSearchControllerWS extends BaseController {
    
    //private ISearchService searchService = new MSearchService();
    //private IPlaceService placeService = new MPlaceService();
    //private IAmenityService amenityService = new MAmenityService();
    
    private ISearchService searchService = new DSearchService();
    private IPlaceService placeService = new DPlaceService();
    private IAmenityService amenityService = new DAmenityService();
    
    public GeoSearchControllerWS() {
            
    }
    
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
                                                 HttpServletResponse response) throws Exception {
        ModelAndView mav = new ModelAndView();
        Map map = new HashMap();        
        String userID = SessionUtils.getUserID(request.getSession());
        
        Map<String, Object> parameterMap = new HashMap<String, Object>();
        if (ServletFileUpload.isMultipartContent(request)) {
            parameterMap = this.getMultipartFormParams(request);
        } 
        else {
            parameterMap = this.getFormParams(request);
        }
        
        Map<String, String> formfields = (Map<String, String>) parameterMap.get("formfields");
        int action = StringUtils.isEmpty(formfields.get("a")) ? 0 : Integer.parseInt(formfields.get("a"));
        
        switch (action) {    
            default: {
                searchMap(mav, map, request);
                break;
            }
        }          
                
        //map.put("host", SystemProperties.SYSTEM_HOST);
        //map.put("port", SystemProperties.SYSTEM_PORT);
        map.put("props", this.getSystemProperties());
        
        mav.setView(new JsonView());
        mav.addObject("model", map);
        return mav;
    }
    
    
    private void search(ModelAndView mav, Map map, HttpServletRequest request) {
        
        String cityName = request.getParameter("cityName");
        String propertyTypeName = request.getParameter("propertyTypeName");
                
        String propertyTypeIDs = request.getParameter("propertyTypeIDs");
        String furnishTypeIDs = request.getParameter("furnishTypeIDs");
        String statusTypeIDs = request.getParameter("statusTypeIDs");
        String amenityIDs = request.getParameter("amenityIDs");
        String placeIDs = request.getParameter("placeIDs");
        
        String sqAreaLow = request.getParameter("sqAreaLow");
        String sqAreaHigh = request.getParameter("sqAreaHigh");
        
        String monthRateLow = request.getParameter("monthRateLow");
        String monthRateHigh = request.getParameter("monthRateHigh");
        
        String numBedroomsLow = request.getParameter("numBedroomsLow");
        String numBedroomsHigh = request.getParameter("numBedroomsHigh");
        String numBathroomsLow = request.getParameter("numBathroomsLow");
        String numBathroomsHigh = request.getParameter("numBathroomsHigh");
        
        String itemsPerPage = request.getParameter("itemsPerPage");
        String pageNumber = request.getParameter("pageNumber");
        
        List<String> propertyTypeIDList = new ArrayList<String>();
        if (propertyTypeName != null && !StringUtils.isEmpty(propertyTypeName)) {
            propertyTypeIDList.add(KPropertyTypes.getIDByTitle(propertyTypeName));            
        }
        if (propertyTypeIDs != null && !StringUtils.isEmpty(propertyTypeIDs)) {
            propertyTypeIDs = propertyTypeIDs.replace("[", "").replace("]", "");
            propertyTypeIDList.addAll(Arrays.asList(propertyTypeIDs.split("\\s*,\\s*")));
        }
                
        List<String> furnishTypeIDList = new ArrayList<String>();
        if (furnishTypeIDs != null && !StringUtils.isEmpty(furnishTypeIDs)) {
            furnishTypeIDs = furnishTypeIDs.replace("[", "").replace("]", "");
            furnishTypeIDList = Arrays.asList(furnishTypeIDs.split("\\s*,\\s*"));
        }
        
        
        //CX: set city filter
        Place city = null;
        if (cityName != null && !StringUtils.isEmpty(cityName)) {
            String cityID = placeService.readIDByTitle(cityName).getResponse();
            city = placeService.readShallow(cityID).getResponse();
        }
        else {
            //CX: use makati as default
            String cityID = placeService.readIDByTitle("Makati").getResponse();
            city = placeService.readShallow(cityID).getResponse();            
        }
        
        List<String> placeIDList = new ArrayList<String>();
        if (city != null) {     
            placeIDList.add(city.getId());
        }
        if (placeIDs != null && !StringUtils.isEmpty(placeIDs)) {
            placeIDs = placeIDs.replace("[", "").replace("]", "");
            placeIDList.addAll(Arrays.asList(placeIDs.split("\\s*,\\s*")));
        }        
        
        List<String> statusTypeIDList = new ArrayList<String>();
        if (statusTypeIDs != null && !StringUtils.isEmpty(statusTypeIDs)) {
            statusTypeIDs = statusTypeIDs.replace("[", "").replace("]", "");
            statusTypeIDList = Arrays.asList(statusTypeIDs.split("\\s*,\\s*"));
        }
        
        List<String> amenityIDList = new ArrayList<String>();
        if (amenityIDs != null && !StringUtils.isEmpty(amenityIDs)) {
            amenityIDs = amenityIDs.replace("[", "").replace("]", "");
            amenityIDList = Arrays.asList(amenityIDs.split("\\s*,\\s*"));
        }
                
        SearchOption option = new SearchOption();
        List<PropertyType> propertyTypes = new ArrayList<PropertyType>();
        List<FurnishType> furnishTypes = new ArrayList<FurnishType>();
        List<StatusType> statusTypes = new ArrayList<StatusType>();
        List<Amenity> amenities = new ArrayList<Amenity>();
        List<Place> places = new ArrayList<Place>();
        
        ListingFilter filter = new ListingFilter();
        
        //CX: get property type s
        if (propertyTypeIDList != null) {
            if (propertyTypeIDList.size() == 0) {
                //propertyTypes.add(KPropertyTypes.HOUSE);
                //propertyTypes.add(KPropertyTypes.CONDOMINIUM);
                //propertyTypes.add(KPropertyTypes.APARTMENT);
                //propertyTypes.add(KPropertyTypes.TOWNHOUSE);
                //propertyTypes.add(KPropertyTypes.ROOM);        
                
                //CX: do not filter property types
                propertyTypes.clear();         
            }
            else {
                if (propertyTypeIDList != null && propertyTypeIDList.size() > 0) {
                    for (String propertyTypeID : propertyTypeIDList) {
                        PropertyType propertyType = KPropertyTypes.getPropertyType(propertyTypeID);
                        if (propertyType != null) {
                            propertyTypes.add(propertyType);
                        } 
                    }
                }                               
            }
        }
        
        //CX: get furnish types
        if (!StringUtils.isEmpty(furnishTypeIDs)) {
            if (StringUtils.equals(furnishTypeIDs, "0")) {
                //propertyTypes.add(KPropertyTypes.HOUSE);
                //propertyTypes.add(KPropertyTypes.CONDOMINIUM);
                //propertyTypes.add(KPropertyTypes.APARTMENT);
                //propertyTypes.add(KPropertyTypes.TOWNHOUSE);
                //propertyTypes.add(KPropertyTypes.ROOM);        
                
                //CX: do not filter property types
                furnishTypes.clear();         
            }
            else {
                if (furnishTypeIDList != null && furnishTypeIDList.size() > 0) {
                    for (String furnishTypeID : furnishTypeIDList) {
                        FurnishType furnishType = KFurnishTypes.getFurnishType(furnishTypeID);
                        if (furnishType != null) {
                            furnishTypes.add(furnishType);
                        } 
                    }
                }                               
            }
        }
        
        //CX: get places
        if (placeIDList != null) {
            if (placeIDList.size() == 0) {
                //CX: do not filter places
                places.clear();
            }
            else {
                if (placeIDList != null && placeIDList.size() > 0) {
                    for (String placeID : placeIDList) {
                        Place place = placeService.read(placeID).getResponse();
                        if (place != null) {
                            places.add(place);
                        }                        
                    }
                }           
            }
        }
               
        //CX: get status types
        if (!StringUtils.isEmpty(statusTypeIDs)) {
            if (StringUtils.equals(statusTypeIDs, "0")) {
                //statusTypes.add(KStatusTypes.FOR_SALE);
                //statusTypes.add(KStatusTypes.FOR_RENT);
                //statusTypes.add(KStatusTypes.FORECLOSED);    
                
                //CX: do not filter status
                statusTypes.clear();       
            }
            else {
                if (statusTypeIDList != null && statusTypeIDList.size() > 0) {
                    for (String statusTypeID : statusTypeIDList) {
                        StatusType statusType = KStatusTypes.getStatusType(statusTypeID);
                        if (statusType != null) {
                            statusTypes.add(statusType);
                        } 
                    }
                }                               
            }
        }
        
        //CX: get amenity types
        if (!StringUtils.isEmpty(amenityIDs)) {
            
            if (StringUtils.equals(amenityIDs, "0")) {
                //CX: do not filter amenities
                amenities.clear();                       
            }
            else {
                if (amenityIDList != null && amenityIDList.size() > 0) {
                    for (String amenityID : amenityIDList) {
                        ServiceResponse<Amenity> sr1 = amenityService.read(amenityID);
                        Amenity amenity = sr1.getResponse();

                        if (amenity != null) {
                            amenities.add(amenity);
                        } 
                    }
                }
            }
        }
        
        //CX: get filters
        if (!StringUtils.isEmpty(sqAreaLow)) { 
            filter.setSqAreaLow(Double.parseDouble(sqAreaLow));            
        }        
        if (!StringUtils.isEmpty(sqAreaHigh)) {
            filter.setSqAreaHigh(Double.parseDouble(sqAreaHigh));            
        }
        
        if (!StringUtils.isEmpty(monthRateLow)) { 
            filter.setMonthRateLow(monthRateLow);            
        }        
        if (!StringUtils.isEmpty(monthRateHigh)) {
            filter.setMonthRateHigh(monthRateHigh);
        }
              
        if (!StringUtils.isEmpty(numBedroomsLow)) { 
            filter.setNumBedroomsLow(Integer.parseInt(numBedroomsLow));
        }        
        if (!StringUtils.isEmpty(numBedroomsHigh)) {
            filter.setNumBedroomsHigh(Integer.parseInt(numBedroomsHigh));
        }
        if (!StringUtils.isEmpty(numBathroomsLow)) { 
            filter.setNumBathroomsLow(Integer.parseInt(numBathroomsLow));
        }        
        if (!StringUtils.isEmpty(numBathroomsHigh)) {
            filter.setNumBathroomsHigh(Integer.parseInt(numBathroomsHigh));
        }        
        
        //CX: set options
        option.setPropertyTypes(propertyTypes);
        option.setFurnishTypes(furnishTypes);
        option.setStatusTypes(statusTypes);
        option.setAmenities(amenities);
        option.setPlaces(places);
        
        option.setListingFilter(filter);
        
        option.setItemsPerPage(StringUtils.isEmpty(itemsPerPage) ? 12 : Integer.parseInt(itemsPerPage.trim()));
        option.setPage(StringUtils.isEmpty(pageNumber) ? 1 : Integer.parseInt(pageNumber.trim()));
        
        //ServiceResponse<List<Listing>> response1 = this.searchService.searchListings(option);  
        ServiceResponse<SearchResult> response1 = this.searchService.searchListings2(option);        
                
        map.put("city", city);         
        map.put("listings", response1.getResponse().getListings());
        map.put("searchResult", response1.getResponse());
        //map.put("option", option);
        //mav.setViewName("listings");        
    }
    
    private void search2(ModelAndView mav, Map map, HttpServletRequest request) {
        String propertyTypeIDs = request.getParameter("propertyTypeIDs");
        String furnishTypeIDs = request.getParameter("furnishTypeIDs");
        String statusTypeIDs = request.getParameter("statusTypeIDs");
        String amenityIDs = request.getParameter("amenityIDs");
        String placeIDs = request.getParameter("placeIDs");
        
        String sqAreaLow = request.getParameter("sqAreaLow");
        String sqAreaHigh = request.getParameter("sqAreaHigh");
        
        String monthRateLow = request.getParameter("monthRateLow");
        String monthRateHigh = request.getParameter("monthRateHigh");
        
        String numBedroomsLow = request.getParameter("numBedroomsLow");
        String numBedroomsHigh = request.getParameter("numBedroomsHigh");
        String numBathroomsLow = request.getParameter("numBathroomsLow");
        String numBathroomsHigh = request.getParameter("numBathroomsHigh");
        
        String itemsPerPage = request.getParameter("itemsPerPage");
        String pageNumber = request.getParameter("pageNumber");
        
        List<String> propertyTypeIDList = new ArrayList<String>();
        if (propertyTypeIDs != null && !StringUtils.isEmpty(propertyTypeIDs)) {
            propertyTypeIDs = propertyTypeIDs.replace("[", "").replace("]", "");
            propertyTypeIDList = Arrays.asList(propertyTypeIDs.split("\\s*,\\s*"));
        }
                
        List<String> furnishTypeIDList = new ArrayList<String>();
        if (furnishTypeIDs != null && !StringUtils.isEmpty(furnishTypeIDs)) {
            furnishTypeIDs = furnishTypeIDs.replace("[", "").replace("]", "");
            furnishTypeIDList = Arrays.asList(furnishTypeIDs.split("\\s*,\\s*"));
        }
        
        List<String> placeIDList = new ArrayList<String>();
        if (placeIDs != null && !StringUtils.isEmpty(placeIDs)) {
            placeIDs = placeIDs.replace("[", "").replace("]", "");
            placeIDList = Arrays.asList(placeIDs.split("\\s*,\\s*"));
        }        
        
        List<String> statusTypeIDList = new ArrayList<String>();
        if (statusTypeIDs != null && !StringUtils.isEmpty(statusTypeIDs)) {
            statusTypeIDs = statusTypeIDs.replace("[", "").replace("]", "");
            statusTypeIDList = Arrays.asList(statusTypeIDs.split("\\s*,\\s*"));
        }
        
        List<String> amenityIDList = new ArrayList<String>();
        if (amenityIDs != null && !StringUtils.isEmpty(amenityIDs)) {
            amenityIDs = amenityIDs.replace("[", "").replace("]", "");
            amenityIDList = Arrays.asList(amenityIDs.split("\\s*,\\s*"));
        }
                
        SearchOption option = new SearchOption();
        List<PropertyType> propertyTypes = new ArrayList<PropertyType>();
        List<FurnishType> furnishTypes = new ArrayList<FurnishType>();
        List<StatusType> statusTypes = new ArrayList<StatusType>();
        List<Amenity> amenities = new ArrayList<Amenity>();
        List<Place> places = new ArrayList<Place>();
        
        ListingFilter filter = new ListingFilter();
        
        //CX: get property types
        if (!StringUtils.isEmpty(propertyTypeIDs)) {
            if (StringUtils.equals(propertyTypeIDs, "0")) {
                //propertyTypes.add(KPropertyTypes.HOUSE);
                //propertyTypes.add(KPropertyTypes.CONDOMINIUM);
                //propertyTypes.add(KPropertyTypes.APARTMENT);
                //propertyTypes.add(KPropertyTypes.TOWNHOUSE);
                //propertyTypes.add(KPropertyTypes.ROOM);        
                
                //CX: do not filter property types
                propertyTypes.clear();         
            }
            else {
                if (propertyTypeIDList != null && propertyTypeIDList.size() > 0) {
                    for (String propertyTypeID : propertyTypeIDList) {
                        PropertyType propertyType = KPropertyTypes.getPropertyType(propertyTypeID);
                        if (propertyType != null) {
                            propertyTypes.add(propertyType);
                        } 
                    }
                }                               
            }
        }
        
        //CX: get furnish types
        if (!StringUtils.isEmpty(furnishTypeIDs)) {
            if (StringUtils.equals(furnishTypeIDs, "0")) {
                //propertyTypes.add(KPropertyTypes.HOUSE);
                //propertyTypes.add(KPropertyTypes.CONDOMINIUM);
                //propertyTypes.add(KPropertyTypes.APARTMENT);
                //propertyTypes.add(KPropertyTypes.TOWNHOUSE);
                //propertyTypes.add(KPropertyTypes.ROOM);        
                
                //CX: do not filter property types
                furnishTypes.clear();         
            }
            else {
                if (furnishTypeIDList != null && furnishTypeIDList.size() > 0) {
                    for (String furnishTypeID : furnishTypeIDList) {
                        FurnishType furnishType = KFurnishTypes.getFurnishType(furnishTypeID);
                        if (furnishType != null) {
                            furnishTypes.add(furnishType);
                        } 
                    }
                }                               
            }
        }
        
        //CX: get places
        if (!StringUtils.isEmpty(placeIDs)) {
            if (StringUtils.equals(placeIDs, "0")) {
                //places.addAll(placeService.readAll(0, 0).getResponse());
                
                //CX: do not filter places
                places.clear();
            }
            else {
                if (placeIDList != null && placeIDList.size() > 0) {
                    for (String placeID : placeIDList) {
                        Place place = placeService.read(placeID).getResponse();
                        if (place != null) {
                            places.add(place);
                        }                        
                    }
                }           
            }
        }
               
        //CX: get status types
        if (!StringUtils.isEmpty(statusTypeIDs)) {
            if (StringUtils.equals(statusTypeIDs, "0")) {
                //statusTypes.add(KStatusTypes.FOR_SALE);
                //statusTypes.add(KStatusTypes.FOR_RENT);
                //statusTypes.add(KStatusTypes.FORECLOSED);    
                
                //CX: do not filter status
                statusTypes.clear();       
            }
            else {
                if (statusTypeIDList != null && statusTypeIDList.size() > 0) {
                    for (String statusTypeID : statusTypeIDList) {
                        StatusType statusType = KStatusTypes.getStatusType(statusTypeID);
                        if (statusType != null) {
                            statusTypes.add(statusType);
                        } 
                    }
                }                               
            }
        }
        
        //CX: get amenity types
        if (!StringUtils.isEmpty(amenityIDs)) {
            
            if (StringUtils.equals(amenityIDs, "0")) {
                //CX: do not filter amenities
                amenities.clear();                       
            }
            else {
                if (amenityIDList != null && amenityIDList.size() > 0) {
                    for (String amenityID : amenityIDList) {
                        ServiceResponse<Amenity> sr1 = amenityService.read(amenityID);
                        Amenity amenity = sr1.getResponse();

                        if (amenity != null) {
                            amenities.add(amenity);
                        } 
                    }
                }
            }
        }
        
        //CX: get filters
        if (!StringUtils.isEmpty(sqAreaLow)) { 
            filter.setSqAreaLow(Double.parseDouble(sqAreaLow));            
        }        
        if (!StringUtils.isEmpty(sqAreaHigh)) {
            filter.setSqAreaHigh(Double.parseDouble(sqAreaHigh));            
        }
        
        if (!StringUtils.isEmpty(monthRateLow)) { 
            filter.setMonthRateLow(monthRateLow);            
        }        
        if (!StringUtils.isEmpty(monthRateHigh)) {
            filter.setMonthRateHigh(monthRateHigh);
        }
              
        if (!StringUtils.isEmpty(numBedroomsLow)) { 
            filter.setNumBedroomsLow(Integer.parseInt(numBedroomsLow));
        }        
        if (!StringUtils.isEmpty(numBedroomsHigh)) {
            filter.setNumBedroomsHigh(Integer.parseInt(numBedroomsHigh));
        }
        if (!StringUtils.isEmpty(numBathroomsLow)) { 
            filter.setNumBathroomsLow(Integer.parseInt(numBathroomsLow));
        }        
        if (!StringUtils.isEmpty(numBathroomsHigh)) {
            filter.setNumBathroomsHigh(Integer.parseInt(numBathroomsHigh));
        }        
        
        //CX: set options
        option.setPropertyTypes(propertyTypes);
        option.setFurnishTypes(furnishTypes);
        option.setStatusTypes(statusTypes);
        option.setAmenities(amenities);
        option.setPlaces(places);
        
        option.setListingFilter(filter);
        
        option.setItemsPerPage(StringUtils.isEmpty(itemsPerPage) ? 1 : Integer.parseInt(itemsPerPage.trim()));
        option.setPage(StringUtils.isEmpty(pageNumber) ? 1 : Integer.parseInt(pageNumber.trim()));
        
        //ServiceResponse<List<Listing>> response1 = this.searchService.searchListings(option);  
        ServiceResponse<SearchResult> response1 = this.searchService.searchListings2(option);        
        
        map.put("searchResult", response1.getResponse());
        map.put("option", option);
        mav.setViewName("listings");
    }
    
    
    private void searchMap(ModelAndView mav, Map map, HttpServletRequest request) {
        
        String cityName = request.getParameter("cityName");
        String propertyTypeName = request.getParameter("propertyTypeName");
                
        String propertyTypeIDs = request.getParameter("propertyTypeIDs");
        String furnishTypeIDs = request.getParameter("furnishTypeIDs");
        String statusTypeIDs = request.getParameter("statusTypeIDs");
        String amenityIDs = request.getParameter("amenityIDs");
        String placeIDs = request.getParameter("placeIDs");
        
        String sqAreaLow = request.getParameter("sqAreaLow");
        String sqAreaHigh = request.getParameter("sqAreaHigh");
        
        String monthRateLow = request.getParameter("monthRateLow");
        String monthRateHigh = request.getParameter("monthRateHigh");
        
        String numBedroomsLow = request.getParameter("numBedroomsLow");
        String numBedroomsHigh = request.getParameter("numBedroomsHigh");
        String numBathroomsLow = request.getParameter("numBathroomsLow");
        String numBathroomsHigh = request.getParameter("numBathroomsHigh");
        
        String itemsPerPage = request.getParameter("itemsPerPage");
        String pageNumber = request.getParameter("pageNumber");
        
        String centerLat = request.getParameter("centerLat");
        String centerLng = request.getParameter("centerLng");
        
        List<String> propertyTypeIDList = new ArrayList<String>();
        if (propertyTypeName != null && !StringUtils.isEmpty(propertyTypeName)) {
            propertyTypeIDList.add(KPropertyTypes.getIDByTitle(propertyTypeName));            
        }
        if (propertyTypeIDs != null && !StringUtils.isEmpty(propertyTypeIDs)) {
            propertyTypeIDs = propertyTypeIDs.replace("[", "").replace("]", "");
            propertyTypeIDList.addAll(Arrays.asList(propertyTypeIDs.split("\\s*,\\s*")));
        }
                
        List<String> furnishTypeIDList = new ArrayList<String>();
        if (furnishTypeIDs != null && !StringUtils.isEmpty(furnishTypeIDs)) {
            furnishTypeIDs = furnishTypeIDs.replace("[", "").replace("]", "");
            furnishTypeIDList = Arrays.asList(furnishTypeIDs.split("\\s*,\\s*"));
        }
                
        //CX: set city filter
        Place city = null;
        if (cityName != null && !StringUtils.isEmpty(cityName)) {
            String cityID = placeService.readIDByTitle(cityName).getResponse();
            city = placeService.readShallow(cityID).getResponse();
        }
        else {
            //CX: use makati as default
            String cityID = placeService.readIDByTitle("Makati").getResponse();
            city = placeService.readShallow(cityID).getResponse();            
        }
        
        List<String> placeIDList = new ArrayList<String>();
        if (city != null) {     
            placeIDList.add(city.getId());
        }
        if (placeIDs != null && !StringUtils.isEmpty(placeIDs)) {
            placeIDs = placeIDs.replace("[", "").replace("]", "");
            placeIDList.addAll(Arrays.asList(placeIDs.split("\\s*,\\s*")));
        }        
        
        List<String> statusTypeIDList = new ArrayList<String>();
        if (statusTypeIDs != null && !StringUtils.isEmpty(statusTypeIDs)) {
            statusTypeIDs = statusTypeIDs.replace("[", "").replace("]", "");
            statusTypeIDList = Arrays.asList(statusTypeIDs.split("\\s*,\\s*"));
        }
        
        List<String> amenityIDList = new ArrayList<String>();
        if (amenityIDs != null && !StringUtils.isEmpty(amenityIDs)) {
            amenityIDs = amenityIDs.replace("[", "").replace("]", "");
            amenityIDList = Arrays.asList(amenityIDs.split("\\s*,\\s*"));
        }
                
        SearchOption option = new SearchOption();
        List<PropertyType> propertyTypes = new ArrayList<PropertyType>();
        List<FurnishType> furnishTypes = new ArrayList<FurnishType>();
        List<StatusType> statusTypes = new ArrayList<StatusType>();
        List<Amenity> amenities = new ArrayList<Amenity>();
        List<Place> places = new ArrayList<Place>();
        
        ListingFilter filter = new ListingFilter();
        
        //CX: get property type s
        if (propertyTypeIDList != null) {
            if (propertyTypeIDList.size() == 0) {
                //propertyTypes.add(KPropertyTypes.HOUSE);
                //propertyTypes.add(KPropertyTypes.CONDOMINIUM);
                //propertyTypes.add(KPropertyTypes.APARTMENT);
                //propertyTypes.add(KPropertyTypes.TOWNHOUSE);
                //propertyTypes.add(KPropertyTypes.ROOM);        
                
                //CX: do not filter property types
                propertyTypes.clear();         
            }
            else {
                if (propertyTypeIDList != null && propertyTypeIDList.size() > 0) {
                    for (String propertyTypeID : propertyTypeIDList) {
                        PropertyType propertyType = KPropertyTypes.getPropertyType(propertyTypeID);
                        if (propertyType != null) {
                            propertyTypes.add(propertyType);
                        } 
                    }
                }                               
            }
        }
        
        //CX: get furnish types
        if (!StringUtils.isEmpty(furnishTypeIDs)) {
            if (StringUtils.equals(furnishTypeIDs, "0")) {
                //propertyTypes.add(KPropertyTypes.HOUSE);
                //propertyTypes.add(KPropertyTypes.CONDOMINIUM);
                //propertyTypes.add(KPropertyTypes.APARTMENT);
                //propertyTypes.add(KPropertyTypes.TOWNHOUSE);
                //propertyTypes.add(KPropertyTypes.ROOM);        
                
                //CX: do not filter property types
                furnishTypes.clear();         
            }
            else {
                if (furnishTypeIDList != null && furnishTypeIDList.size() > 0) {
                    for (String furnishTypeID : furnishTypeIDList) {
                        FurnishType furnishType = KFurnishTypes.getFurnishType(furnishTypeID);
                        if (furnishType != null) {
                            furnishTypes.add(furnishType);
                        } 
                    }
                }                               
            }
        }
        
        //CX: get places
        if (placeIDList != null) {
            if (placeIDList.size() == 0) {
                //CX: do not filter places
                places.clear();
            }
            else {
                if (placeIDList != null && placeIDList.size() > 0) {
                    for (String placeID : placeIDList) {
                        Place place = placeService.read(placeID).getResponse();
                        if (place != null) {
                            places.add(place);
                        }                        
                    }
                }           
            }
        }
               
        //CX: get status types
        if (!StringUtils.isEmpty(statusTypeIDs)) {
            if (StringUtils.equals(statusTypeIDs, "0")) {
                //statusTypes.add(KStatusTypes.FOR_SALE);
                //statusTypes.add(KStatusTypes.FOR_RENT);
                //statusTypes.add(KStatusTypes.FORECLOSED);    
                
                //CX: do not filter status
                statusTypes.clear();       
            }
            else {
                if (statusTypeIDList != null && statusTypeIDList.size() > 0) {
                    for (String statusTypeID : statusTypeIDList) {
                        StatusType statusType = KStatusTypes.getStatusType(statusTypeID);
                        if (statusType != null) {
                            statusTypes.add(statusType);
                        } 
                    }
                }                               
            }
        }
        
        //CX: get amenity types
        if (!StringUtils.isEmpty(amenityIDs)) {
            
            if (StringUtils.equals(amenityIDs, "0")) {
                //CX: do not filter amenities
                amenities.clear();                       
            }
            else {
                if (amenityIDList != null && amenityIDList.size() > 0) {
                    for (String amenityID : amenityIDList) {
                        ServiceResponse<Amenity> sr1 = amenityService.read(amenityID);
                        Amenity amenity = sr1.getResponse();

                        if (amenity != null) {
                            amenities.add(amenity);
                        } 
                    }
                }
            }
        }
        
        //CX: get filters
        if (!StringUtils.isEmpty(sqAreaLow)) { 
            filter.setSqAreaLow(Double.parseDouble(sqAreaLow));            
        }        
        if (!StringUtils.isEmpty(sqAreaHigh)) {
            filter.setSqAreaHigh(Double.parseDouble(sqAreaHigh));            
        }
        
        if (!StringUtils.isEmpty(monthRateLow)) { 
            filter.setMonthRateLow(monthRateLow);            
        }        
        if (!StringUtils.isEmpty(monthRateHigh)) {
            filter.setMonthRateHigh(monthRateHigh);
        }
              
        if (!StringUtils.isEmpty(numBedroomsLow)) { 
            filter.setNumBedroomsLow(Integer.parseInt(numBedroomsLow));
        }        
        if (!StringUtils.isEmpty(numBedroomsHigh)) {
            filter.setNumBedroomsHigh(Integer.parseInt(numBedroomsHigh));
        }
        if (!StringUtils.isEmpty(numBathroomsLow)) { 
            filter.setNumBathroomsLow(Integer.parseInt(numBathroomsLow));
        }        
        if (!StringUtils.isEmpty(numBathroomsHigh)) {
            filter.setNumBathroomsHigh(Integer.parseInt(numBathroomsHigh));
        }        
        
        //CX: set options
        option.setPropertyTypes(propertyTypes);
        option.setFurnishTypes(furnishTypes);
        option.setStatusTypes(statusTypes);
        option.setAmenities(amenities);
        option.setPlaces(places);
        
        option.setListingFilter(filter);
        
        option.setItemsPerPage(StringUtils.isEmpty(itemsPerPage) ? 12 : Integer.parseInt(itemsPerPage.trim()));
        option.setPage(StringUtils.isEmpty(pageNumber) ? 1 : Integer.parseInt(pageNumber.trim()));
        
        if (StringUtils.isEmpty(centerLat) && StringUtils.isEmpty(centerLng)) {
            option.setCenterPoint( new LatLng(Double.parseDouble(centerLat), Double.parseDouble(centerLng)) );            
        }
        
        //ServiceResponse<List<Listing>> response1 = this.searchService.searchListings(option);  
        ServiceResponse<SearchResult> response1 = this.searchService.searchPlacesGeo(option);        
                
        map.put("city", city);         
        map.put("listings", response1.getResponse().getListings());
        map.put("searchResult", response1.getResponse());
        //map.put("option", option);
        //mav.setViewName("listings");        
    }
}